package com.aspire.nm.component.cmppserver.handler;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executor;

import javax.annotation.Resource;

import org.apache.mina.core.session.IoSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.aspire.nm.component.cmppserver.CmppServer;
import com.aspire.nm.component.cmppserver.deliverListenerDefault.DeliverListenerImpl;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppDeliverPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppSubmitPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppSubmitRespPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.Version;
import com.aspire.nm.component.cmppserver.runTime.SysRunTimeService;
import com.aspire.nm.component.cmppserver.util.LogService;
import com.aspire.nm.component.cmppserver.util.MessageIdGenerator;
import com.aspire.nm.component.commonUtil.date.DateUtil;


@Service
public class ProcessSubmitManager{

    
    
    @Resource
    private CmppServer cmppServer;
    
	@Resource(name="submitExecutor")
	private Executor submitExecutor;
	
	@Resource
    private SysRunTimeService sysRunTimeService;
	
	@Value("${cmppserver.splitSubmitMsg}")
    private boolean splitSubmitMsg;
	
	@Value("${cmppserver.syncProcessSubmit}")
    private boolean syncProcessSubmit;
	
	@Value("${autoDeliver}")
    private boolean autoDeliver;
	
	@Resource
    private LogService logService;
	
	
	public int process(IoSession session,CmppSubmitPacket cmppSubmitPacket,CmppSubmitRespPacket cmppSubmitRespPacket){
	    if(syncProcessSubmit){
	        return processSync(session,cmppSubmitPacket,cmppSubmitRespPacket);
	    }else{
	        return processAsync(session,cmppSubmitPacket,cmppSubmitRespPacket);
	    }
	}
	
	
	public int processAsync(IoSession session,CmppSubmitPacket cmppSubmitPacket,CmppSubmitRespPacket cmppSubmitRespPacket){
		submitExecutor.execute(new Thread(){
			private CmppSubmitPacket cmppSubmitPacket;
			private CmppSubmitRespPacket cmppSubmitRespPacket;
			private IoSession session;
			public Runnable setParams(IoSession session,CmppSubmitPacket cmppSubmitPacket,CmppSubmitRespPacket cmppSubmitRespPacket){
				this.cmppSubmitPacket = cmppSubmitPacket;
				this.cmppSubmitRespPacket = cmppSubmitRespPacket;
				this.session = session;
				return this;
			}
			public void run(){
			    processSync(session,cmppSubmitPacket,cmppSubmitRespPacket);
			}
		}.setParams(session,cmppSubmitPacket,cmppSubmitRespPacket));
		return CmppSubmitRespPacket.RESULT_OK;
	}


	
	
	private int processSync(IoSession session,CmppSubmitPacket cmppSubmitPacket,CmppSubmitRespPacket cmppSubmitRespPacket){
	    String clientIp = ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress();
	    String user = sysRunTimeService.getUserRunTime(session).getUser();
	    
	    if(cmppServer.getProcessSubmit() != null){
            if(splitSubmitMsg){
                String[] terminals = cmppSubmitPacket.getDestTerminalId();
                Version version = sysRunTimeService.getUserRunTime(session).getConnection(session).getVersion();
                for(String terminal:terminals){
                    CmppSubmitPacket cmppSubmitPacketSingle = new CmppSubmitPacket(version);
                    BeanUtils.copyProperties(cmppSubmitPacket, cmppSubmitPacketSingle);
                    cmppSubmitPacketSingle.setDestTerminalId(new String[]{terminal});
                    
                    logService.processSubmit(session, cmppSubmitPacketSingle);
                    int result =  cmppServer.getProcessSubmit().process(cmppSubmitPacketSingle,cmppSubmitRespPacket,user,clientIp);
                    if(autoDeliver && result == CmppSubmitRespPacket.RESULT_OK){
                        autoDeliver(cmppSubmitPacket,cmppSubmitRespPacket,user,clientIp);
                    }
                    return result;
                }
            }else{
                logService.processSubmit(session, cmppSubmitPacket);
                int result = cmppServer.getProcessSubmit().process(cmppSubmitPacket,cmppSubmitRespPacket,user,clientIp);
                if(autoDeliver && result == CmppSubmitRespPacket.RESULT_OK){
                    autoDeliver(cmppSubmitPacket,cmppSubmitRespPacket,user,clientIp);
                }
                return result;
            }
        }
	    return CmppSubmitRespPacket.RESULT_OK;
	}
	
	
	
	
	
	
	private void autoDeliver(CmppSubmitPacket cmppSubmitPacket, CmppSubmitRespPacket cmppSubmitRespPacket, String user,String clientIp){
        
        new Thread(){
            
            private CmppSubmitPacket cmppSubmitPacket;
            private CmppSubmitRespPacket cmppSubmitRespPacket;
            private String user;
            public Thread setParams(CmppSubmitPacket cmppSubmitPacket,CmppSubmitRespPacket cmppSubmitRespPacket,String user){
                this.cmppSubmitPacket = cmppSubmitPacket;
                this.cmppSubmitRespPacket = cmppSubmitRespPacket;
                this.user = user;
                return this;
            }
            
            public void run(){
                
                setPriority(Thread.MIN_PRIORITY);
                Thread.yield();
                

                CmppDeliverPacket cmppDeliverPacket = new CmppDeliverPacket();
                
                if(cmppSubmitPacket.getRegisteredDelivery() == 1){
                    //自动返回状态报告
                    cmppDeliverPacket.setDestId(cmppSubmitPacket.getSrcId());
                    cmppDeliverPacket.setDestTerminalId(cmppSubmitPacket.getDestTerminateIds());
                    cmppDeliverPacket.setRegisteredDelivery(true);
                    cmppDeliverPacket.setSrcTerminalId(cmppSubmitPacket.getDestTerminateIds());
                    cmppDeliverPacket.setSrcTerminalType((byte)0);
                    cmppDeliverPacket.setServiceId(cmppSubmitPacket.getServiceId());
                    cmppDeliverPacket.setMsgId(MessageIdGenerator.getMessageIdGenerator().getMsgId((short)0));
                    cmppDeliverPacket.setIsmgMsgId(cmppSubmitRespPacket.getMsgId());
                    cmppDeliverPacket.setStat("DELIVERD");
                    cmppDeliverPacket.setSubmitTime(DateUtil.getCurDateTimeFormat("yyMMddHHmm"));
                    cmppDeliverPacket.setDoneTime(DateUtil.getCurDateTimeFormat("yyMMddHHmm"));
                    try {
                        cmppDeliverPacket.setLinkId("linkid");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    cmppDeliverPacket.setMsgFmt((byte)15);
                    
                }else{
                    //自动返回上行
                    cmppDeliverPacket.setDestId(cmppSubmitPacket.getSrcId());
                    cmppDeliverPacket.setDestTerminalId(cmppSubmitPacket.getDestTerminateIds());
                    cmppDeliverPacket.setRegisteredDelivery(false);
                    cmppDeliverPacket.setSrcTerminalId(cmppSubmitPacket.getDestTerminateIds());
                    cmppDeliverPacket.setSrcTerminalType((byte)0);
                    cmppDeliverPacket.setServiceId(cmppSubmitPacket.getServiceId());
                    cmppDeliverPacket.setMsgContent(cmppSubmitPacket.getMsgContent());
                    cmppDeliverPacket.setMsgId(MessageIdGenerator.getMessageIdGenerator().getMsgId((short)0));
                    try {
                        cmppDeliverPacket.setLinkId("linkid");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    cmppDeliverPacket.setMsgFmt((byte)15);
                    
                }
                DeliverListenerImpl.instance.put(user, cmppDeliverPacket);
            }
        }.setParams(cmppSubmitPacket, cmppSubmitRespPacket, user).start();
    }
}
